package com.buybuyyi.stylistcrm.security.dao.impl;

import com.buybuyyi.stylistcrm.security.dao.UserDao;
import com.buybuyyi.stylistcrm.security.mapper.SecurityNavigationMapper;
import com.buybuyyi.stylistcrm.security.mapper.SecurityUserMapper;
import com.buybuyyi.stylistcrm.security.po.SecurityNavigation;
import com.buybuyyi.stylistcrm.security.po.SecurityOperationPermission;
import com.buybuyyi.stylistcrm.security.po.SecurityUser;
import com.buybuyyi.stylistcrm.security.po.SecurityViewPermission;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import stylistcrm.core.services.security.dto.NavigationDto;
import stylistcrm.core.services.security.dto.OperationAuthorityDto;
import stylistcrm.core.services.security.dto.UserDto;
import stylistcrm.core.services.security.dto.ViewAuthorityDto;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by yanwc on 2016/9/10.
 */
@Repository
public class UserDaoImpl implements UserDao {

    private static Logger _logger = Logger.getLogger(UserDaoImpl.class);
    //导航菜单最大层数
    private static int NAVIGATIONMAXLAYER=100;

    private int currentLayer = 0;

    @Autowired
    SecurityUserMapper securityUserMapper;

    @Autowired
    SecurityNavigationMapper securityNavigationMapper;

    @Override
    public UserDto findUserByUserName(String userName) {
        UserDto userDto = null;
        SecurityUser user = securityUserMapper.selectByUserName(userName);
        if (user != null) {
            userDto = new UserDto();
            userDto.setEnable(user.getIsEnable());
            userDto.setLock(user.getIsLock());
            userDto.setPassword(user.getPassword());
            userDto.setId(user.getId());
            userDto.setLoginName(user.getLoginName());
            userDto.setUserName(userName);

            List<SecurityNavigation> securityNavigationList = securityNavigationMapper.selectAll();
            //初始化当前用户操作权限
            userDto.setListOperationAuthority(getOperationAuthority(userName));
            //初始化当前用户视图权限
            userDto.setListViewAuthority(getViewAuthority(userName, securityNavigationList));
            //初始化当前用户导航菜单
            userDto.setNavigation(getNavigation(userName, securityNavigationList));
        }
        return userDto;
    }

    /**
     * 获取用户的导航菜单
     *
     * @param userName
     * @param securityNavigationList
     * @return
     */
    private NavigationDto getNavigation(String userName, List<SecurityNavigation> securityNavigationList) {
        NavigationDto root = null;
        if (securityNavigationList == null) {
            return root;
        }
        List<SecurityNavigation> userSecurityNavigation =
                securityUserMapper.selectNavigationByUserName(userName);
        //定义菜单根
        if (securityNavigationList != null) {
            root = new NavigationDto();
            root.setName("菜单");//TODO 读取配置文件
            root.setCode("root");
            root.setRemark("系统菜单");
            root.setSort(new BigDecimal(0));
            root.setParent(null);
            this.currentLayer = 0;//初始化计数器
            for (SecurityNavigation n : securityNavigationList) {
                if (n.getParentId() == null || n.getParentId() ==0) {
                    NavigationDto nav = this.toNavigationDto(n,userSecurityNavigation);
                    if(nav != null){
                        buildSubNavigation(nav,securityNavigationList,userSecurityNavigation);
                        root.add(nav);
                    }
                }
            }
        }
        return root;
    }

    /**
     * 根据用户的导航菜单权限将导航菜单转换为dto对象     *
     * @param secNav
     * @param userSecurityNavigation
     * @return
     */
    private NavigationDto toNavigationDto(SecurityNavigation secNav, List<SecurityNavigation> userSecurityNavigation){
        //查找当前菜单子菜单
        NavigationDto nav = new NavigationDto();
        nav.setId(secNav.getId());
        nav.setCode(secNav.getCode());
        //nav.setParent(nav);
        nav.setName(secNav.getName());
        nav.setRemark(secNav.getRemark());
        nav.setSort(secNav.getSort());

        return nav;
    }

    /**
     * 获取菜单子菜单
     * 递归调用
     * @param navDto
     * @param securityNavigationList
     * @param userSecurityNavigation
     */
    private void  buildSubNavigation(NavigationDto navDto,
                                      List<SecurityNavigation> securityNavigationList,
                                      List<SecurityNavigation> userSecurityNavigation){
        this.currentLayer++;
        for(SecurityNavigation secNav :securityNavigationList){
            if(navDto.getId()== secNav.getParentId()){
                //判断用户时候有当前菜单权限
                boolean isRight = false;
                for(SecurityNavigation tmpNav:userSecurityNavigation){
                    if(tmpNav.getId() == secNav.getId()){
                        isRight = true;
                        break;
                    }
                }
                if(!isRight){
                    continue;
                }
                NavigationDto nav =  this.toNavigationDto(secNav,userSecurityNavigation);
                if(nav != null){
                    if(this.currentLayer>NAVIGATIONMAXLAYER){
                        _logger.warn(String.format("加载导航菜单错误，导航菜单嵌套层数超过最大限制层数{0}",NAVIGATIONMAXLAYER));
                        return;
                    }
                    buildSubNavigation(nav,securityNavigationList,userSecurityNavigation);
                    navDto.add(nav);
                }
            }
        }
    }
    /**
     * 获取操作权限
     *
     * @param userName
     * @return
     */
    public List<OperationAuthorityDto> getOperationAuthority(String userName) {
        List<OperationAuthorityDto> operationAuthorityDtoList = null;
        List<SecurityOperationPermission> securityOperationPermissionList =
                securityUserMapper.selectOperationPermissionByUserName(userName);
        if (securityOperationPermissionList != null) {
            operationAuthorityDtoList = new ArrayList<>();
            for (SecurityOperationPermission p : securityOperationPermissionList) {
                OperationAuthorityDto operDto = new OperationAuthorityDto();
                operDto.setCode(p.getAuthorCode());
                operDto.setName(p.getName());
                operDto.setViewName(p.getViewName());
                operationAuthorityDtoList.add(operDto);
            }
        }
        return operationAuthorityDtoList;
    }

    /**
     * 获取用户视图权限
     *
     * @param userName
     * @return
     */
    private List<ViewAuthorityDto> getViewAuthority(String userName, List<SecurityNavigation> securityNavigationList) {
        List<ViewAuthorityDto> viewAuthorityDtoList = new ArrayList<ViewAuthorityDto>();
        List<SecurityViewPermission> securityViewPermissionList =
                securityUserMapper.selectViewPermissionByUserName(userName);
        if (securityViewPermissionList != null) {
            for (SecurityViewPermission p : securityViewPermissionList) {
                ViewAuthorityDto viewDto = new ViewAuthorityDto();
                viewDto.setCode(p.getAuthorCode());
                viewDto.setName(p.getName());
                SecurityNavigation navigation = null;
                if (securityNavigationList != null) {
                    for (SecurityNavigation nav : securityNavigationList) {
                        if (nav.getId() == p.getNavigationId()) {
                            navigation = nav;
                            break;
                        }
                    }
                }
                if (navigation != null) {
                    NavigationDto navigationDto = new NavigationDto();
                    navigationDto.setName(navigation.getName());
                    navigation.setCode(navigation.getCode());
                    navigation.setParentId(navigation.getParentId());
                    navigation.setRemark(navigation.getRemark());
                    navigation.setSort(navigation.getSort());
                    navigation.setId(navigation.getId());
                    viewDto.setNavigationDto(navigationDto);
                    viewAuthorityDtoList.add(viewDto);
                }
            }
        }
        return viewAuthorityDtoList;
    }
}
